import * as cc from "cc";
import yyComponent from "../../Script/Common/yyComponent";
import { EventType } from "../../Script/GameSpecial/GameEventType";
import Action3dManager, { ActionMngType } from "../../Script/Common/Action3dManager";
import RecommendManager from "../../Script/Recommend/RecommendManager";
import UIManager from "../../Script/Common/UIManager";
import PlayerData from "../../Script/Common/PlayerData";
import AudioManager from "../../Script/Common/AudioManager";
import GameData from "../../Script/Common/GameData";
import PowerManager from "../../Script/Common/PowerManager";
import Loader from "../../Script/Common/Loader";
import { GlobalEnum } from "../../Script/GameSpecial/GlobalEnum";
import GlobalPool from "../../Script/Common/GlobalPool";
import GlobalData from "../../Script/Common/GlobalData";
import AdvertManager from "../../Script/Common/AdvertManager";
import MapData from "../../Script/GameSpecial/MapData";

const { ccclass, property } = cc._decorator;

/**游戏流程管理器，挂载在游戏主场景根节点 */
@ccclass
export default class GameDirector extends yyComponent {

    @property(cc.Node)
    protected skyCamera: cc.Node = null;
    @property(cc.Node)
    protected bg: cc.Node = null;

    start() {
        this.init();
        this.loadGameData();
    }

    update(dt) {
        this.uiActMng.update(dt);
        this.customUpdate(dt);
    }

    /************************************快捷方法************************************/
    //#region 触摸遮罩
    /**出没遮罩层，阻挡玩家触摸操作 */
    @property(cc.Node)
    protected touchMask: cc.Node = null;
    /**记录需要显示遮罩的次数，次数为0时隐藏遮罩层 */
    protected touchMaskCount: number;
    protected initTouchMask() {
        this.touchMask.active = false;
        this.touchMaskCount = 0;
    }
    protected resetTouchMask() {
        this.touchMask.active = false;
        this.touchMaskCount = 0;
    }
    /**显示一层遮罩，阻挡玩家操作 */
    protected showTouchMask(count: number = 1) {
        this.touchMaskCount += count;
        this.touchMask.active = true;
    }
    /**移除一层遮罩，遮罩层数为0时玩家才能进行操作 */
    protected hideTouchMask(count: number = 1) {
        this.touchMaskCount -= count;
        if (this.touchMaskCount <= 0) {
            this.touchMaskCount = 0;
            this.touchMask.active = false;
        }
    }
    //#endregion

    //#region 关卡暂停/继续快捷方法
    /**暂停关卡 */
    protected pauseLevel() {
        this.emit(EventType.Common.DirectorEvent.pauseLevel);
    }
    /**恢复关卡 */
    protected resumeLevel() {
        this.emit(EventType.Common.DirectorEvent.resumeLevel);
    }
    //#endregion

    //#region UI显隐快捷方法
    protected showUIs(uis) {
        for (let i = uis.length - 1; i >= 0; --i) {
            this.emit(EventType.Common.UIEvent.enter, uis[i]);
        }
    }
    protected hideUIs(uis) {
        for (let i = uis.length - 1; i >= 0; --i) {
            this.emit(EventType.Common.UIEvent.exit, uis[i]);
        }
    }
    //#endregion

    /************************************管理的对象************************************/
    //#region 已经存在的UI
    @property([yyComponent])
    protected defaultUIs: yyComponent[] = [];
    protected initDefaultUIs() {
        for (let i = this.defaultUIs.length - 1; i >= 0; --i) {
            this.defaultUIs[i].init();
            // this.defaultUIs[i].hide();
        }
    }
    //#endregion

    //#region UI分类
    //只能在首页中时才显示的UI
    protected lobbyUIs = [];
    //只能在关卡中时才显示的UI
    protected levelUIs = [];
    //可在任意情况下显示的UI
    protected persistUIs = [];
    protected initUIConfig() {
        this.lobbyUIs = [];
        this.lobbyUIs.push(GlobalEnum.UI.lobby);
        this.lobbyUIs.push(GlobalEnum.UI.shop);
        this.lobbyUIs.push(GlobalEnum.UI.spin);
        this.lobbyUIs.push(GlobalEnum.UI.chooseLevel);
        this.lobbyUIs.push(GlobalEnum.UI.tryMaxCar);

        this.levelUIs = [];
        this.levelUIs.push(GlobalEnum.UI.levelInfo);
        this.levelUIs.push(GlobalEnum.UI.levelController);
        this.levelUIs.push(GlobalEnum.UI.levelTeach);
        this.levelUIs.push(GlobalEnum.UI.awardUI);
        this.levelUIs.push(GlobalEnum.UI.winUI);
        this.levelUIs.push(GlobalEnum.UI.loseUI);
        this.levelUIs.push(GlobalEnum.UI.trySkin);
        this.levelUIs.push(GlobalEnum.UI.pauseLevel);
        this.levelUIs.push(GlobalEnum.UI.resurgence);
        this.levelUIs.push(GlobalEnum.UI.match);

        this.persistUIs = [];
        this.persistUIs.push(GlobalEnum.UI.playerAssetBar);
        this.persistUIs.push(GlobalEnum.UI.tipPower);
        this.persistUIs.push(GlobalEnum.UI.getPower);
        this.persistUIs.push(GlobalEnum.UI.configSetting);

    }
    //#endregion

    //#region UI动作管理器
    protected uiActMng: Action3dManager = null;
    protected initActMng() {
        this.uiActMng = Action3dManager.getMng(ActionMngType.UI);
    }
    //#endregion

    /**关卡场景管理器 */
    protected levelMng: any = null;

    //#region 天空盒与首页背景
    //天空盒
    protected updateSkyBox() {
        let skys = MapData.getSceneStyleData().sky;
        let index = Math.floor(Math.random() * (skys.length - 0.001));
        let sky = skys[index];
        Loader.loadBundleRes("MainScene", "sky/" + sky, (img) => {
            let scene = cc.director.getScene();
            scene._globals._skybox.envmap = img;
        });
        // Loader.loadBundleRes("MainScene", "Image/" + sky + "/textureCube", (img) => {
        //     let scene = cc.director.getScene();
        //     scene._globals._skybox.envmap = img;
        // });
    }
    protected onCreateMapDataFinish() {
        this.updateSkyBox();
    }
    //#endregion

    /************************************子包管理************************************/

    /************************************游戏流程************************************/
    //#region 脚本通用流程
    public init() {
        this.initUIConfig();
        this.initActMng();
        this.initTouchMask();
        this.initModels();
        this.initDefaultUIs();
        this.initCustomUpdateState();
        this.registAllCustomUpdate();
        this.onEvents();
    }

    protected initModels() {
        let cvs = this.node;
        GlobalData.set(GlobalEnum.Common.GlobalDataType.canvas, cvs);
        let cvsTransf = cvs.getComponent(cc.UITransform);
        GlobalData.set(GlobalEnum.Common.GlobalDataType.canvasTransform, cvsTransf);

        //互推
        let rootRecommend = this.node.getChildByName("Recommend");
        GlobalData.set(GlobalEnum.Common.GlobalDataType.rootRecommond, rootRecommend);
        if (!!rootRecommend && rootRecommend.active) {
            RecommendManager.init(rootRecommend);
        }
        //广告
        AdvertManager.init();
        //UI
        let rootUI = this.node.getChildByName("UI");
        GlobalData.set(GlobalEnum.Common.GlobalDataType.rootUI, rootUI);
        UIManager.init(rootUI);

        AudioManager.init();
        GameData.init();
        PowerManager.init();
        // OnlineTimeManager.init();
        // TaskManager.init();


        //白鹰SDK-原生广告节点
        let nativeAd = this.node.getChildByName("NativeAd");
        this.emit(EventType.Common.HeyGameSDK.initAdNode, nativeAd);

    }

    protected onEvents() {
        this.on(EventType.Common.DirectorEvent.enterLevel, this.onEnterLevel, this);
        this.on(EventType.Common.DirectorEvent.enterLobby, this.enterGameLobby, this);
        this.on(EventType.Common.DirectorEvent.playerWin, this.onLevelWin, this);
        this.on(EventType.Common.DirectorEvent.playerLose, this.onLevelLose, this);
        this.on(EventType.Common.DirectorEvent.hideGameLobby, this.hideGameLobbyUI, this);
        this.on(EventType.Common.DirectorEvent.chooseTrySkinFinish, this.onChooseTrySkinFinish, this);

        this.on(EventType.Common.UIEvent.showTouchMask, this.showTouchMask, this);
        this.on(EventType.Common.UIEvent.hideTouchMask, this.hideTouchMask, this);

        this.on(EventType.LevelEvent.resurgence, this.onResurgence, this);
        this.on(EventType.LevelEvent.matchFinish, this.onMatchFinish, this);

        this.on(EventType.LevelEvent.mapDataCreateFinish, this.onCreateMapDataFinish, this);
    }
    protected registAllCustomUpdate() {
        this.registCustomUpdate(GlobalEnum.DirectState.level, this.stepLevelPlaying);
        this.registCustomUpdate(GlobalEnum.DirectState.lobby, this.stepLobby);
    }

    public reset() {
        if (!!this.levelMng) this.levelMng.exit();
        this.resetTouchMask();
        this.resetCustomUpdateState();
    }
    //#endregion

    //#region 游戏数据加载
    /**加载全部游戏数据（json文件） */
    protected loadGameData() {
        Loader.loadBundleDir("MainScene", "JSONData", (res) => {
            let urls = [];
            for (let i = 0, c = res.length; i < c; ++i) {
                urls.push(res[i].name);
            }
            GameData.setData(res, urls);
            this.showUI(GlobalEnum.UI.lobby);
            this.showLevelMapLobby();
            this.enterCustomUpdateState(GlobalEnum.DirectState.lobby);
        }, cc.JsonAsset, false);
    }
    //#endregion

    //#region 游戏流程：进入/退出首页
    //进入首页
    protected enterGameLobby() {
        // if (!!this.levelMng) this.levelMng.exit();
        this.showLevelMapLobby();
        this.hideUIs(this.levelUIs);
        this.hideUIs(this.persistUIs);
        this.showUI(GlobalEnum.UI.lobby);
        this.showUI(GlobalEnum.UI.playerAssetBar);
        this.enterCustomUpdateState(GlobalEnum.DirectState.lobby);
    }
    protected showLevelMapLobby() {
        let lv = this.getCurLevel();
        MapData.createRandomMap(lv);
        if (!!this.levelMng) {
            this.levelMng.enterLobby();
            return;
        }
        Loader.loadBundle("LevelScene", () => {
            Loader.loadBundleDir("LevelScene", "MultiplePrefab", (res) => {
                for (let i = res.length - 1; i >= 0; --i) {
                    let r = res[i];
                    GlobalPool.createPool(r.data.name, r, r.data.name);
                }
                Loader.loadBundleRes("LevelScene", "SinglePrefab/LevelManager", (res) => {
                    if (!this.levelMng) {
                        let node = cc.instantiate(res);
                        cc.director.getScene().addChild(node);
                        this.levelMng = node.getComponent("LevelManager");
                        this.levelMng.init();
                        this.levelMng.enterLobby();
                    }
                    this.skyCamera.active = false;
                    // this.bg.active = false;
                    let fadeOut = Action3dManager.fadeTo(2, 1);
                    fadeOut.easing(Action3dManager.easeIn(2));
                    let cb = Action3dManager.callFun(() => {
                        this.bg.active = false;
                    });
                    let seq = Action3dManager.sequence(fadeOut, cb);
                    Action3dManager.getMng(ActionMngType.UI).runAction(this.bg, seq);

                }, cc.Prefab, true);
            }, cc.Prefab, true);
        }, true, true);
    }
    //隐藏首页UI 
    protected hideGameLobbyUI() {
        this.bg.active = false;
        this.skyCamera.active = false;
        this.hideUIs(this.lobbyUIs);
        this.hideUIs(this.persistUIs);
        this.hideUI(GlobalEnum.UI.lobby);
    }
    //#endregion

    //#region 游戏流程：进入关卡
    //开始游戏：
    protected onEnterLevel(level?: number) {
        this.chosedLevel = level;
        if (!this.levelMng) {
            this.loadLevelScene();
        } else {
            this.checkEnterLevelScene();
        }
    }

    //获取玩家当前能进入的关卡
    protected getCurLevel(): number {
        // console.error("测试阶段，关卡序号固定为1");
        // return 1;
        return PlayerData.getData("gameData.curLevel");
    }

    //皮肤试用界面
    protected showTrySkin() {
        this.pauseLevel();
        this.showUI(GlobalEnum.UI.trySkin, GlobalEnum.GoodsType.playerSkin);
    }
    //试用皮肤流程结束(不论玩家是否选择了试用皮肤)
    protected onChooseTrySkinFinish() {
        this.hideUI(GlobalEnum.UI.trySkin);
        this.showTeachAnim();
    }

    //显示教学动画
    protected showTeachAnim() {
        return;
        this.emit(EventType.Common.DirectorEvent.pauseLevel);
        Loader.loadBundleRes("UI", "TeachAnim/TeachAnim", (res) => {
            let layer = GlobalData.get(GlobalEnum.Common.GlobalDataType.rootUI).getChildByName("TeachAnim");
            let node = layer.children[0];
            if (!node) {
                node = cc.instantiate(res);
                layer.addChild(node);
                node.getComponent("TeachAnim").init();
            }
            let js = node.getComponent("TeachAnim");
            js.startTeach(this.levelMng);
            this.emit(EventType.Common.DirectorEvent.resumeLevel);
            this.emit(EventType.Common.UIEvent.enter, GlobalEnum.UI.levelTeach);
        }, cc.Prefab, true);
    }
    //#endregion

    //#region 进入战斗场景
    protected loadLevelScene() {
        Loader.loadBundle("LevelScene", () => {
            Loader.loadBundleDir("LevelScene", "MultiplePrefab", (res) => {
                for (let i = res.length - 1; i >= 0; --i) {
                    let r = res[i];
                    GlobalPool.createPool(r.data.name, r, r.data.name);
                }
                Loader.loadBundleRes("LevelScene", "SinglePrefab/LevelManager", (res) => {
                    if (!this.levelMng) {
                        let node = cc.instantiate(res);
                        cc.director.getScene().addChild(node);
                        this.levelMng = node.getComponent("LevelManager");
                        this.levelMng.init();
                    }
                    this.onLoadLevelFinish();
                    //预加载结算界面
                    // Loader.loadBundle("UI", () => {
                    //     Loader.loadBundleArray("UI", [
                    //         "AwardUI/AwardUI",
                    //         "WinUI/WinUI",
                    //         "LoseUI/LoseUI",
                    //     ], () => { }, cc.Prefab, false);
                    // }, false, false);
                }, cc.Prefab, true);
            }, cc.Prefab, true);
        }, false, true);
    }
    protected onLoadLevelFinish() {
        this.checkEnterLevelScene();
    }
    //匹配界面
    protected matchFinished: boolean = false;
    protected onMatchFinish() {
        this.matchFinished = true;
        this.checkEnterLevelScene();
    }

    protected checkEnterLevelScene() {
        if (!this.levelMng) return;
        // if (!this.matchFinished) return;
        this.matchFinished = false;
        this.enterLevelScene();
    }
    /**关卡数据 */
    protected levelData: any;
    protected chosedLevel: number = null;
    protected enterLevelScene(level?: number) {
        if (!!this.levelData) {
            let levelData = this.levelData;
            this.levelData = null;
            this.chosedLevel = null;
            this._enterLevelScene(levelData);
        } else {
            if (undefined === level) {
                if (!!this.chosedLevel) {
                    level = this.chosedLevel;
                } else {
                    level = this.getCurLevel();
                }
            }
            this.chosedLevel = null;
            GameData.getLevelData(level, this._enterLevelScene.bind(this));
        }
    }
    protected _enterLevelScene(levelData) {
        //进入关卡:
        this.hideGameLobbyUI();
        this.hideUIs(this.levelUIs);
        this.hideUI(GlobalEnum.UI.playerAssetBar);
        this.levelMng.enterLevel(levelData);
        this.emit(EventType.Common.DirectorEvent.pauseLevel, 2);//2:两次暂停，等2个UI全部加装完毕再继续游戏:levelInfoUI,levelController
        this.showUI(GlobalEnum.UI.levelInfo, levelData);
        // //教学UI必须依赖于操作UI，故先加载操作UI，再进入游戏
        Loader.loadBundle("UI", () => {
            Loader.loadBundleRes("UI", "LevelController/LevelController", (res) => {
                let layer = GlobalData.get(GlobalEnum.Common.GlobalDataType.rootUI).getChildByName("LevelController");
                let node = layer.children[0];
                if (!node) {
                    node = cc.instantiate(res);
                    layer.addChild(node);
                    let ctrl = node.getComponent("LevelController");
                    ctrl.init();
                }
                this.showUI(GlobalEnum.UI.levelController);
                this.emit(EventType.Common.DirectorEvent.resumeLevel);
                if (levelData.lv == 1) {
                    this.showTeachAnim();
                }
            }, cc.Prefab, true);
        }, false, true);
        this.enterCustomUpdateState(GlobalEnum.DirectState.level);
    }
    //#endregion

    //#region 游戏流程：关卡胜利
    //关卡胜利
    protected winData: any;
    protected onLevelWin(data?) {
        if (!data) {
            data = UIManager.getUI(GlobalEnum.UI.levelInfo).getData();//从UI获取关卡成绩
        }
        this.winData = data;
        this.updateLevelRecord(data);
        this.addCurLevel(data);
        this.showUI(GlobalEnum.UI.winUI, this.winData);
    }
    //关卡进度+1
    protected addCurLevel(data) {
        let config = cc.sys.localStorage.getItem("levelDataVersion");
        let totalLevel = 10;
        if (!!config) {
            config = JSON.parse(config);
            totalLevel = config.total;
        }
        let lv = PlayerData.getData("gameData.curLevel");
        console.log("通关当前关卡，解锁下一关，curLevel:", lv, " totalLevel:", totalLevel);
        // if (data.lv === lv && lv + 1 <= totalLevel) {
        this.emit(EventType.Common.PlayerDataEvent.updatePlayerData, {
            type: "gameData",
            attribute: "gameData.curLevel",
            value: 1,
            mode: "+",
        });
        // }
    }
    //记录关卡成绩
    protected updateLevelRecord(data: { lv: number, star: number }) {
        if (undefined === data.star) return;
        let record = PlayerData.getData("gameData.levelRecords");
        if (!record[data.lv] || record[data.lv] < data.star) {
            record[data.lv] = data.star;
            this.emit(EventType.Common.PlayerDataEvent.updatePlayerData, {
                attribute: "gameData.levelRecords",
                value: record,
                mode: "=",
                save: true,
                emit: false,
            });
        }
    }
    //#endregion

    //#region 游戏流程：关卡失败
    //关卡失败
    protected loseData: any;
    protected onLevelLose(data?) {
        if (!data) {
            data = UIManager.getUI(GlobalEnum.UI.levelInfo).getData();
        }
        this.loseData = data;
        this.showUI(GlobalEnum.UI.loseUI, this.loseData);
    }
    //#endregion

    //#region 游戏流程：失败后重玩
    //复活
    protected onResurgence() {
        this.hideUIs(this.lobbyUIs);
        this.hideUI(GlobalEnum.UI.playerAssetBar);
    }
    //#endregion

    //#region 游戏运行状态
    protected stepLobby(dt: number) {
        if (!!this.levelMng) {
            this.levelMng.running(dt);
        }
    }
    protected stepLevelPlaying(dt: number) {
        this.levelMng.running(dt);
    }
    //#endregion
}
